/*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    nf-core/deepmodeloptim Nextflow config file
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Default config options for all compute environments
----------------------------------------------------------------------------------------
*/

// Global default params, used in configs
params {

    // Input options
    data                    = null // TODO either change one of the params above by input or create a samplesheet containing the info of them
    model                   = null                   // the model file in python, the model that will be tested by this pipeline
    data_config             = null                   // the config file that specifies all the parameters relative to the data manipulation
    model_config            = null                   // the config file with all the hyperparameter directives (choiches) and all ray tune specs
    preprocessing_config    = null                   // the config file that specifies the data preprocessing steps

    // Optional inputs
    initial_weights         = null                   // the initial weights of the model. These files can be used to start the training instead of random initialization. One can provide several files, each of them will be used for a different run.

    // Input options for data preprocessing protocols
    genome                  = null
    igenomes_base           = 's3://ngi-igenomes/igenomes/'
    bed_peak_size           = 300                   // the size of the region around the peak that will be centered

    // Tuning options
    tune_trials_range       = null                  // the number of trials for the tuning step e.g. "10,20,5" will do 10, 15 and 20 trials
    tune_replicates         = 1                     // the number of replicates for each trial #
    prediction_data         = null                  // the file with the data to predict for evaluation purposes

    // Output options
    outdir                  = "./results/"          // the outdir has to be the one the user specify _ the unique name of the run _ the time so that multiple runs will not overlap
    publish_dir_mode        = "copy"
    save_data               = false                 // save transformed data or not

    // Computational resources
    max_gpus                = 1                      // requesting the gpus for the tuning steps.
    // TODO this should not be in the nextflow config but in each config
    // max_cpus                = 12                      // this flasg and the following are for regulating resources, profiles can overwrite these.
    // max_memory              = 32.GB
    // max_time                = "72.h"

    // Error options
    max_retries             = 0
    err_start               = 'finish'

    // Optional flags
    check_model             = true                   // flag to tell whether to check or not if the model can be tuned and trained. It does one call of the batch function, (predicting), of the model importing and using everything needed for that. Default run such a check.
    check_model_num_samples = null                   // optional flag to do a more extensive check during check_model. This will override user given num_sample value for the tune run. This will give the user control on how extensive it wants the check to be.
    shuffle                 = true                   // flag to tell wether to shuffle or not the data and run a train on it. Sanity check always run on default. (If the way we think at shuffle change maybe is better to remove this flag and make it into a parameter of the user given json for noise nad split)
    debug_mode              = false                  // flag used to switch to debug mode for the pipeline.

    // Development stage options
    // please change them in dev.config
    container_dev           = null

    // General
    help                    = false
    validate_params         = true                     // tells wether or not to validate input values using nf-schema.


    // Boilerplate options
    outdir                       = null
    publish_dir_mode             = 'copy'
    email                        = null
    email_on_fail                = null
    plaintext_email              = false
    monochrome_logs              = false
    hook_url                     = null
    help                         = false
    help_full                    = false
    show_hidden                  = false
    version                      = false
    pipelines_testdata_base_path = 'https://raw.githubusercontent.com/nf-core/test-datasets/'
    trace_report_suffix          = new java.util.Date().format( 'yyyy-MM-dd_HH-mm-ss')// Config options
    config_profile_name        = null
    config_profile_description = null

    custom_config_version      = 'master'
    custom_config_base         = "https://raw.githubusercontent.com/nf-core/configs/${params.custom_config_version}"
    config_profile_contact     = null
    config_profile_url         = null

    // Schema validation default options
    validate_params            = true
}

// Load base.config by default for all pipelines
includeConfig 'conf/base.config'

profiles {
    debug {
        dumpHashes              = true
        process.beforeScript    = 'echo $HOSTNAME'
        cleanup                 = false
        nextflow.enable.configProcessNamesValidation = true
    }
    conda {
        conda.enabled           = true
        docker.enabled          = false
        singularity.enabled     = false
        podman.enabled          = false
        shifter.enabled         = false
        charliecloud.enabled    = false
        conda.channels          = ['conda-forge', 'bioconda']
        apptainer.enabled       = false
    }
    mamba {
        conda.enabled           = true
        conda.useMamba          = true
        docker.enabled          = false
        singularity.enabled     = false
        podman.enabled          = false
        shifter.enabled         = false
        charliecloud.enabled    = false
        apptainer.enabled       = false
    }
    docker {
        docker.enabled          = true
        conda.enabled           = false
        singularity.enabled     = false
        podman.enabled          = false
        shifter.enabled         = false
        charliecloud.enabled    = false
        apptainer.enabled       = false
        docker.runOptions       = '-u $(id -u):$(id -g)'
    }
    arm {
        docker.runOptions       = '-u $(id -u):$(id -g) --platform=linux/amd64'
    }
    singularity {
        singularity.enabled     = true
        singularity.autoMounts  = true
        conda.enabled           = false
        docker.enabled          = false
        podman.enabled          = false
        shifter.enabled         = false
        charliecloud.enabled    = false
        apptainer.enabled       = false
    }
    podman {
        podman.enabled          = true
        conda.enabled           = false
        docker.enabled          = false
        singularity.enabled     = false
        shifter.enabled         = false
        charliecloud.enabled    = false
        apptainer.enabled       = false
    }
    shifter {
        shifter.enabled         = true
        conda.enabled           = false
        docker.enabled          = false
        singularity.enabled     = false
        podman.enabled          = false
        charliecloud.enabled    = false
        apptainer.enabled       = false
    }
    charliecloud {
        charliecloud.enabled    = true
        conda.enabled           = false
        docker.enabled          = false
        singularity.enabled     = false
        podman.enabled          = false
        shifter.enabled         = false
        apptainer.enabled       = false
    }
    apptainer {
        apptainer.enabled       = true
        apptainer.autoMounts    = true
        conda.enabled           = false
        docker.enabled          = false
        singularity.enabled     = false
        podman.enabled          = false
        shifter.enabled         = false
        charliecloud.enabled    = false
    }
    wave {
        apptainer.ociAutoPull   = true
        singularity.ociAutoPull = true
        wave.enabled            = true
        wave.freeze             = true
        wave.strategy           = 'conda,container'
    }
    gitpod {
        executor.name           = 'local'
        executor.cpus           = 4
        executor.memory         = 8.GB
        process {
            resourceLimits = [
                memory: 8.GB,
                cpus  : 4,
                time  : 1.h
            ]
        }
    }
    test         { includeConfig "conf/test.config"       }
    test_stub    { includeConfig "conf/test_stub.config"  }
    test_ibis    { includeConfig "conf/test_ibis.config"  }
    test_ibis_with_preprocessing { includeConfig "conf/test_ibis_with_preprocessing.config" }
    test_noise_eval { includeConfig "conf/test_noise_eval.config" }
    local        { includeConfig "conf/local.config"      }
    dev          { includeConfig "conf/dev.config"        }
}

// Load nf-core custom profiles from different Institutions
includeConfig !System.getenv('NXF_OFFLINE') && params.custom_config_base ? "${params.custom_config_base}/nfcore_custom.config" : "/dev/null"

// Load igenomes.config if required
if (params.genome == null) {
    params.genomes = [:]
} else {
    includeConfig 'conf/igenomes.config'
}

// Load nf-core/deepmodeloptim custom profiles from different institutions.
// TODO This line can be uncommented once you move the pipeline to nf-core. A file deepmodeloptim.config will be automatically created at the nf-core/configs repo. This is to allow having a pipeline specific config.
// includeConfig !System.getenv('NXF_OFFLINE') && params.custom_config_base ? "${params.custom_config_base}/pipeline/deepmodeloptim.config" : "/dev/null"

// Set default registry for Apptainer, Docker, Podman, Charliecloud and Singularity independent of -profile
// Will not be used unless Apptainer / Docker / Podman / Charliecloud / Singularity are enabled
// Set to your registry if you have a mirror of containers
apptainer.registry    = 'quay.io'
docker.registry       = 'quay.io'
podman.registry       = 'quay.io'
singularity.registry  = 'quay.io'
charliecloud.registry = 'quay.io'



// Export these variables to prevent local Python/R libraries from conflicting with those in the container
// The JULIA depot path has been adjusted to a fixed path `/usr/local/share/julia` that needs to be used for packages in the container.
// See https://apeltzer.github.io/post/03-julia-lang-nextflow/ for details on that. Once we have a common agreement on where to keep Julia packages, this is adjustable.

env {
    PYTHONNOUSERSITE = 1
    R_PROFILE_USER   = "/.Rprofile"
    R_ENVIRON_USER   = "/.Renviron"
    JULIA_DEPOT_PATH = "/usr/local/share/julia"
}

// Set bash options
process.shell = [
    "bash",
    "-C",         // No clobber - prevent output redirection from overwriting files.
    "-e",         // Exit if a tool returns a non-zero status/exit code
    "-u",         // Treat unset variables and parameters as an error
    "-o",         // Returns the status of the last command to exit..
    "pipefail"    //   ..with a non-zero status or zero if all successfully execute
]

// Disable process selector warnings by default. Use debug profile to enable warnings.
nextflow.enable.configProcessNamesValidation = false

timeline {
    enabled = true
    file    = "${params.outdir}/pipeline_info/execution_timeline_${params.trace_report_suffix}.html"
}
report {
    enabled = true
    file    = "${params.outdir}/pipeline_info/execution_report_${params.trace_report_suffix}.html"
}
trace {
    enabled = true
    file    = "${params.outdir}/pipeline_info/execution_trace_${params.trace_report_suffix}.txt"
}
dag {
    enabled = true
    file    = "${params.outdir}/pipeline_info/pipeline_dag_${params.trace_report_suffix}.html"
}

manifest {
    name            = 'nf-core/deepmodeloptim'
    author          = """Mathys Grapotte""" // The author field is deprecated from Nextflow version 24.10.0, use contributors instead
    contributors    = [
        // TODO nf-core: Update the field with the details of the contributors to your pipeline. New with Nextflow version 24.10.0
        [
            name: 'Mathys Grapotte',
            affiliation: '',
            email: '',
            github: '',
            contribution: [], // List of contribution types ('author', 'maintainer' or 'contributor')
            orcid: ''
        ],
    ]
    homePage        = 'https://github.com/nf-core/deepmodeloptim'
    description     = """nf-core/deepmodeloptim is an end-to-end pipeline designed to facilitate the testing and development of deep learning models for genomics."""
    mainScript      = 'main.nf'
    defaultBranch   = 'master'
    nextflowVersion = '!>=24.04.2'
    version         = '1.0.0dev'
    doi             = ''
}

// Nextflow plugins
plugins {
    id 'nf-schema@2.3.0' // Validation of pipeline parameters and creation of an input channel from a sample sheet
}

validation {
    defaultIgnoreParams = ["genomes", "data", "data_config", "model_config"]
    monochromeLogs = params.monochrome_logs
    help {
        enabled = true
        command = "nextflow run nf-core/deepmodeloptim -profile <docker/singularity/.../institute> --input samplesheet.csv --outdir <OUTDIR>"
        fullParameter = "help_full"
        showHiddenParameter = "show_hidden"
        beforeText = """
-\033[2m----------------------------------------------------\033[0m-
                                        \033[0;32m,--.\033[0;30m/\033[0;32m,-.\033[0m
\033[0;34m        ___     __   __   __   ___     \033[0;32m/,-._.--~\'\033[0m
\033[0;34m  |\\ | |__  __ /  ` /  \\ |__) |__         \033[0;33m}  {\033[0m
\033[0;34m  | \\| |       \\__, \\__/ |  \\ |___     \033[0;32m\\`-._,-`-,\033[0m
                                        \033[0;32m`._,._,\'\033[0m
\033[0;35m  nf-core/deepmodeloptim ${manifest.version}\033[0m
-\033[2m----------------------------------------------------\033[0m-
"""
        afterText = """${manifest.doi ? "\n* The pipeline\n" : ""}${manifest.doi.tokenize(",").collect { "    https://doi.org/${it.trim().replace('https://doi.org/','')}"}.join("\n")}${manifest.doi ? "\n" : ""}
* The nf-core framework
    https://doi.org/10.1038/s41587-020-0439-x

* Software dependencies
    https://github.com/nf-core/deepmodeloptim/blob/master/CITATIONS.md
"""
    }
    summary {
        beforeText = validation.help.beforeText
        afterText = validation.help.afterText
    }
}

// Load modules.config for DSL2 module specific options
includeConfig 'conf/modules.config'
